/*
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License");  you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * http//www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 *
 * The Original Code is ART Ontology API.
 *
 * The Initial Developer of the Original Code is University of Roma Tor Vergata.
 * Portions created by University of Roma Tor Vergata are Copyright (C) 2007.
 * All Rights Reserved.
 *
 * ART Ontology API was developed by the Artificial Intelligence Research Group
 * (art.uniroma2.it) at the University of Roma Tor Vergata
 * Current information about the ART Ontology API can be obtained at 
 * http//art.uniroma2.it/owlart
 *
 */

/*
 * Contributor(s): Armando Stellato stellato@info.uniroma2.it
 */
package it.uniroma2.art.owlart.models;

import it.uniroma2.art.owlart.exceptions.ModelAccessException;
import it.uniroma2.art.owlart.exceptions.ModelUpdateException;
import it.uniroma2.art.owlart.model.ARTResource;
import it.uniroma2.art.owlart.model.ARTURIResource;
import it.uniroma2.art.owlart.navigation.ARTLiteralIterator;
import it.uniroma2.art.owlart.navigation.ARTResourceIterator;
import it.uniroma2.art.owlart.navigation.ARTURIResourceIterator;

/**
 * Interface for OWL (1.0) compliant models
 * 
 * @author Armando Stellato
 * 
 */
public interface OWLModel extends RDFSModel, OWLReasoner {

	/**
	 * adds an annotation property with uri = <code>propertyURI</code>
	 * 
	 * @param propertyURI
	 * @param superProperty
	 * @param graphs
	 * @throws ModelUpdateException
	 */
	public abstract void addAnnotationProperty(String propertyURI, ARTURIResource superProperty,
			ARTResource... graphs) throws ModelUpdateException;

	/**
	 * adds a datatype property with uri = <code>propertyURI</code>
	 * 
	 * @param propertyURI
	 * @param superProperty
	 * @param graphs
	 * @throws ModelUpdateException
	 */
	public abstract void addDatatypeProperty(String propertyURI, ARTURIResource superProperty,
			ARTResource... graphs) throws ModelUpdateException;

	/**
	 * adds an object property with uri = <code>propertyURI</code>
	 * 
	 * @param propertyURI
	 * @param superProperty
	 * @param graphs
	 * @throws ModelUpdateException
	 */
	public abstract void addObjectProperty(String propertyURI, ARTURIResource superProperty,
			ARTResource... graphs) throws ModelUpdateException;

	
	/**
	 * adds an ontology property with uri = <code>propertyURI</code>
	 * 
	 * @param propertyURI
	 * @param superProperty
	 * @param graphs
	 * @throws ModelUpdateException
	 */
	public abstract void addOntologyProperty(String propertyURI, ARTURIResource superProperty,
			ARTResource... graphs) throws ModelUpdateException;
	
	
	/**
	 * adds an import statement to the given ontology graphs. Note that this method should be commonly invoked
	 * on the main graph, since the subject of the import is the uri of the main ontology of this model.
	 * However, the methods allows to state the import also in other graphs
	 * 
	 * @param baseURI
	 *            the baseURI of the ontology being imported
	 * @param graphs
	 * @throws ModelUpdateException
	 */
	public abstract void addImportStatement(String baseURI, ARTResource... graphs)
			throws ModelUpdateException;

	/**
	 * creates a triple for the given <code>subject</code>, <code>predicate</code> and <code>value</code><br/>
	 * Arguments are already constrained considering the type of property which is being instantiated
	 * 
	 * @param subject
	 * @param predicate
	 * @param value
	 * @param graphs
	 * @throws ModelUpdateException
	 * 
	 * @deprecated use {@link RDFModel#instantiatePropertyWithPlainLiteral(ARTResource, ARTURIResource, String, ARTResource...)}
	 */
	public abstract void instantiateDatatypeProperty(ARTResource subject, ARTURIResource predicate,
			String value, ARTResource... graphs) throws ModelUpdateException;

	/**
	 * creates a triple for the given <code>subject</code>, <code>predicate</code> and <code>object</code><br/>
	 * Arguments are already constrained considering the type of property which is being instantiated
	 * 
	 * @param subject
	 * @param predicate
	 * @param object
	 * @param graphs
	 * @throws ModelUpdateException
	 * 
	 * @deprecated use {@link RDFModel#instantiatePropertyWithResource(ARTResource, ARTURIResource, ARTResource, ARTResource...)}
	 */
	public abstract void instantiateObjectProperty(ARTResource subject, ARTURIResource predicate,
			ARTResource object, ARTResource... graphs) throws ModelUpdateException;

	/**
	 * creates a triple for the given <code>subject</code>, <code>predicate</code> and object, which is
	 * described by its label (<code>value</code>) and language (<code>lang</code>)<br/>
	 * Arguments are already constrained considering the type of property which is being instantiated
	 * 
	 * @param subject
	 * @param property
	 * @param value
	 * @param lang
	 * @throws ModelUpdateException
	 * 
	 * @deprecated use {@link RDFModel#instantiatePropertyWithPlainLiteral(ARTResource, ARTURIResource, String, String, ARTResource...)}
	 */
	public void instantiateAnnotationProperty(ARTResource subject, ARTURIResource property, String value,
			String lang, ARTResource... graphs) throws ModelUpdateException;

	/**
	 * checks that prop is an Annotation property
	 * 
	 * @param prop
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract boolean isAnnotationProperty(ARTURIResource prop, ARTResource... graphs)
			throws ModelAccessException;
	
	/**
	 * checks that prop is an Ontology property
	 * 
	 * @param prop
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract boolean isOntologyProperty(ARTURIResource prop, ARTResource... graphs)
			throws ModelAccessException;

	/**
	 * checks that prop is an Datatype property
	 * 
	 * @param prop
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract boolean isDatatypeProperty(ARTURIResource prop, ARTResource... graphs)
			throws ModelAccessException;

	/**
	 * checks that prop is a Functional property
	 * 
	 * @param property
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract boolean isFunctionalProperty(ARTURIResource property, ARTResource... graphs)
			throws ModelAccessException;

	/**
	 * checks that prop is an InverseFunctional property
	 * 
	 * @param property
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract boolean isInverseFunctionalProperty(ARTURIResource property, ARTResource... graphs)
			throws ModelAccessException;

	/**
	 * checks that prop is an Object property
	 * 
	 * @param prop
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract boolean isObjectProperty(ARTURIResource prop, ARTResource... graphs)
			throws ModelAccessException;

	/**
	 * checks that prop is a Symmetric property
	 * 
	 * @param property
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract boolean isSymmetricProperty(ARTURIResource property, ARTResource... graphs)
			throws ModelAccessException;

	/**
	 * checks that prop is a Transitive property
	 * 
	 * @param property
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract boolean isTransitiveProperty(ARTURIResource property, ARTResource... graphs)
			throws ModelAccessException;

	/**
	 * 
	 * checks if the resource (which has been probably returned has the range of a datatype property, is a
	 * DataRange)
	 * 
	 * @param range
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract boolean isDataRange(ARTResource range, ARTResource... graphs) throws ModelAccessException;

	/**
	 * checks that resource <code>uri</code> is an Ontology
	 * 
	 * @param uri
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract boolean isOntology(ARTURIResource uri, ARTResource... graphs) throws ModelAccessException;

	/**
	 * returns an iterator over datatype properties available from graphs <code>graphs</code>
	 * 
	 * @param inferred
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract ARTURIResourceIterator listDatatypeProperties(boolean inferred, ARTResource... graphs)
			throws ModelAccessException;

	/**
	 * returns an iterator over object properties available from graphs <code>graphs</code>
	 * 
	 * @param inferred
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract ARTURIResourceIterator listObjectProperties(boolean inferred, ARTResource... graphs)
			throws ModelAccessException;

	/**
	 * returns an iterator over Annotation properties available from graphs <code>graphs</code>
	 * 
	 * @param inferred
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract ARTURIResourceIterator listAnnotationProperties(boolean inferred, ARTResource... graphs)
			throws ModelAccessException;
	
	
	/**
	 * returns an iterator over Ontology properties available from graphs <code>graphs</code>
	 * 
	 * @param inferred
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract ARTURIResourceIterator listOntologyProperties(boolean inferred, ARTResource... graphs)
			throws ModelAccessException;

	/**
	 * returns the inverse property of <code>objectProperty</code>. If more than one inverse is defined, the
	 * first declared one is returned (all other properties are equivalentProperties then). If no declaration
	 * is available, null is returned.
	 * 
	 * @param objectProperty
	 * @param inferred
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract ARTURIResource getInverseProperty(ARTURIResource objectProperty, boolean inferred,
			ARTResource... graphs) throws ModelAccessException;

	/**
	 * list all ontologies imported by ontology <code>ontology</code> (defined in graphs <code>graphs</code>
	 * 
	 * @param ontology
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract ARTURIResourceIterator listOntologyImports(ARTURIResource ontology, ARTResource... graphs)
			throws ModelAccessException;

	/**
	 * returns an iterator over the list of values bound to individual <code>individual</code> through
	 * datatype/annotation property <code>property</code> both parameters need to be instantiated
	 * 
	 * @param instance
	 * @param property
	 * @param inferred
	 * @return
	 */
	public abstract ARTLiteralIterator listValuesOfSubjDTypePropertyPair(ARTResource instance,
			ARTURIResource property, boolean inferred, ARTResource... graphs) throws ModelAccessException;

	/**
	 * returns an iterator over the list of values bound to individual <code>individual</code> through object
	 * property <code>property</code> both parameters need to be instantiated
	 * 
	 * @param individual
	 * @param property
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract ARTResourceIterator listValuesOfSubjObjPropertyPair(ARTResource individual,
			ARTURIResource property, boolean inferred, ARTResource... graphs) throws ModelAccessException;

	/**
	 * returns an iterator over the list of values allowed by this datarange
	 * 
	 * @param dataRange
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract ARTLiteralIterator parseDataRange(ARTResource dataRange, ARTResource... graphs)
			throws ModelAccessException;

	/**
	 * removes an import statement from graphs <code>graphs</code>
	 * 
	 * @param URI
	 *            the baseURI of the ontology being imported
	 * @param graphs
	 * @throws ModelUpdateException
	 */
	public abstract void removeImportStatement(ARTURIResource URI, ARTResource... graphs)
			throws ModelUpdateException;

}